#include <cstddef>
#include <iostream>
#include <string>

static bool CheckUTF8FollowingBytes(const char *first, size_t count) {
  for (size_t i = 1; i <= count; ++i) {
    unsigned char c = *(first + i);
    if (c >> 6 != 2) {
      return false;
    }
  }
  return true; 
}

ssize_t GetStrVisualLengthUTF8(const char *str) {
  ssize_t visual_length = 0;

  for (const char *p = str; *p != 0;) {
    unsigned char c = *p;

    if (c >> 7 == 0x0) {
      // single byte
      ++visual_length;
      ++p;
    } else if (c >> 5 == 0x06) {
      // double bytes
      if (CheckUTF8FollowingBytes(p, 1) == false) {
        return -1;
      }
      visual_length += 2;
      p += 2;
    } else if (c >> 4 == 0x0e) {
      // three bytes
      if (CheckUTF8FollowingBytes(p, 2) == false) {
        return -1;
      }
      visual_length += 2;
      p += 3;
    } else if (c >> 3 == 0x1e) {
      // four bytes
      if (CheckUTF8FollowingBytes(p, 3) == false) {
        return -1;
      }
      visual_length += 2;
      p += 4;
    } else {
      return -1;
    }
  }

  return visual_length;
}

int main(void)
{
    std::cout << GetStrVisualLengthUTF8("中国123") << std::endl;
    return 0;
}
